package be.kuleuven.cs.mop.util;


import static be.kuleuven.cs.mop.util.HTML.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.ResourceType;
import be.kuleuven.cs.mop.domain.model.Task;
import be.kuleuven.cs.mop.domain.model.UserType;
import be.kuleuven.cs.mop.domain.model.impl.Field;
import be.kuleuven.cs.mop.domain.model.impl.Interval;
import be.kuleuven.cs.mop.domain.model.impl.Schedule;



/**
 * Utility class
 */
public final class Utils {
	
	private static final DateFormat	DATE_FORMAT	=
		new SimpleDateFormat("dd-MM-yy @ HH:mm");
	
	
	
	public static final String format(final Calendar cal) {
		return DATE_FORMAT.format(cal.getTime());
	}
	
	public static final String format(final long time) {
		final long t = (time % (24 * 60 * 60 * 1000));
		final long h	= (t / (60 * 60 * 1000));
		final long m	= ((t % (60 * 60 * 1000)) / (60 * 1000));
		return new StringBuilder(5)
		.append((h < 10) ? ("0" + h) : h)
		.append(':')
		.append((m < 10) ? ("0" + m) : m)
		.toString();
	}
	
	public static final String format(final String name, final Field field) {
		return String.format("[%s] &nbsp; %s &nbsp; = &nbsp; %s",
				field.getType(), name, field.getValue());
	}
	
	public static final String format(final Task task, final boolean full) {
		String status = task.getStatus().toString();
		if (status.equals("UNFINISHED"))
			status = ((task.isAvailable() ? "" : "UN") + "AVAILABLE");
		
		final StringBuilder sb = new StringBuilder().append(
				table(
						row(cell("User: &nbsp; "), cell(task.getUser())),
						row(cell("State: &nbsp; "), cell(status))
				)
		);
		
		sb.append("<br>");
		
		sb.append("Type:<br> &nbsp; &nbsp; &nbsp; ");
		sb.append(task.getType().getName());
		
		if (full) {
			sb.append("<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
			sb.append("Resources:<br>");
			for (final Entry<? extends ResourceType, Interval> entry : task.getType().getRequiredResourceTypes().entrySet()) {
				sb.append(" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
				sb.append(entry.getKey().getName());
				sb.append("<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
				sb.append(String.format("[%d - %d]", entry.getValue().getLowerLimit(), entry.getValue().getUpperLimit()));
				sb.append("<br>");
			}
			
			sb.append("<br>");
			
			sb.append(" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
			sb.append("Helpers:<br>");
			for (final Entry<? extends UserType, Interval> entry : task.getType().getHelperUserTypesConstraints().entrySet()) {
				sb.append(" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
				sb.append(entry.getKey().getName());
				sb.append("<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");
				sb.append(String.format("[%d - %d]", entry.getValue().getLowerLimit(), entry.getValue().getUpperLimit()));
				sb.append("<br>");
			}
		}
		
		sb.append("<br>");
		
		sb.append("Project:<br> &nbsp; &nbsp; &nbsp; ");
		try {
			sb.append(task.getProject());
		} catch (final TaskManagerException e) {
			sb.append("<i>none</i>");
		}
		sb.append("<br><br>");
		
		final Schedule schedule = task.getSchedule();
		sb.append("Schedule:<br>")
		.append(" &nbsp; &nbsp; &nbsp; From: &nbsp; ")
		.append(schedule.getStartDate().getTime())
		.append("<br>")
		.append(" &nbsp; &nbsp; &nbsp; To: &nbsp; &nbsp; ")
		.append(schedule.getDeadline().getTime())
		.append("<br>")
		.append(" &nbsp; &nbsp; &nbsp; Duration: &nbsp; ")
		.append(schedule.getDuration() / 60000)
		.append(" minute(s)<br><br>");
		
		final Collection<? extends Task> dep = task.getDependencies();
		sb.append("Dependencies:<br>");
		if (dep.isEmpty())
			sb.append(" &nbsp; &nbsp; &nbsp; <i>none</i><br>");
		else
			for (final Task t : dep)
				sb.append(" &nbsp; &nbsp; &nbsp; ").append(t).append("<br>");
		
		sb.append("<br>");
		
		final Map<String, Field> fields = task.getFields();
		sb.append("Fields:<br>");
		if (fields.isEmpty()) {
			sb.append(" &nbsp; &nbsp; &nbsp; <i>none</i><br>");
		} else {
			for (final Entry<String, Field> entry : fields.entrySet()) {
				sb.append(" &nbsp; &nbsp; &nbsp; ")
				.append(format(entry.getKey(), entry.getValue())).append("<br>");
			}
		}
		
		return wrap(sb.toString());
	}
	
}